/*
 * libArchivoLog.c
 *
 *  Created on: 14/04/2012
 *      Author: utnso
 */

#include "libArchivoLog.h"

//VARIABLES GLOBALES PURAMENTE A ESTE ARCHIVO
static int32_t fp = -1;
static char pathArchLog[MAX_PATH_LONG];
static uint8_t nivelLogActual = NIVEL_LOG_OBLIGATORIO;
static pthread_mutex_t mutexArchLogs = PTHREAD_MUTEX_INITIALIZER;

void inicializarPathLogueo(char* path) {
	memset(pathArchLog, '\0', MAX_PATH_LONG);
	strcpy(pathArchLog, path);
}

void inicializarNivelLogueo(uint8_t nivelLog) {
	if (nivelLog >= NIVEL_LOG_NULO && nivelLog <= NIVEL_LOG_ALTO_IMPR) {
		nivelLogActual = nivelLog;
	} else if (nivelLog < NIVEL_LOG_NULO) {
		nivelLogActual = NIVEL_LOG_NULO;
	} else {
		nivelLogActual = NIVEL_LOG_ALTO_IMPR;
	}
}

void loguearCadena(char* cadena, uint8_t nivelLog) {
	//LA CADENA DEBE TERMINAR EN \n Y NO DEBE CONTENER \0
	if (nivelLogActual > 0 && nivelLogActual >= nivelLog) {
		pthread_mutex_lock(&mutexArchLogs);
		//ESTA SETEADO EL NIVEL DE LOG NECESARIO PARA LOGUEAR ESTE EVENTO
		if (div(nivelLogActual, 2).rem == 0) {
			//EL NIVEL DE LOG ES PAR, ADEMAS DE LOGUEAR EL EVENTO EN UN ARCHIVO SE IMPRIME POR CONSOLA
			printf("%s", cadena);
		}
		if (fp == -1) {
			//NO SE CUENTA CON INFORMACION DEL ARCHIVO
			fp = open(pathArchLog, O_WRONLY | O_CREAT | O_TRUNC, 0600);
		}

		write(fp, cadena, strlen(cadena));
		pthread_mutex_unlock(&mutexArchLogs);
	}
}

void loguearDatos(char* tipo, time_t tiempo, char* nombreProceso, uint32_t idProceso, uint32_t idThread, char* comentario, uint8_t nivelLog) {
	if (nivelLogActual > 0 && nivelLogActual >= nivelLog) {
		/*//SE PASARA AL FORMATO [tipo] horas:minutos:segundos:milisegundos nombreProceso/(idProceso:idThread): comentario\n
		 char* buffer = (char*) malloc(200);
		 memset(buffer, '\0', 200);

		 //CASTEO EL TIEMPO A CHAR
		 struct tm* tiempoLocal;
		 tiempoLocal = localtime(&tiempo);
		 strftime(buffer, 80, "%H:%M:%S:000", tiempoLocal);
		 char* bufferTiempo = (char*) malloc(strlen(buffer) + 1);
		 memset(bufferTiempo, '\0', strlen(buffer) + 1);
		 strcpy(bufferTiempo, buffer);

		 //CASTEO EL ID DEL PROCESO A CHAR
		 char* bufferIdProceso;
		 intAChar(&bufferIdProceso, idProceso, 10);

		 //CASTEO EL ID DEL THREAD A CHAR
		 char* bufferIdThread;
		 intAChar(&bufferIdThread, idThread, 10);

		 char* cadena = malloc(1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1 + strlen(bufferIdProceso) + 1 + strlen(bufferIdThread) + 1 + 1 + 1 + strlen(comentario) + 1 + 1);
		 memset(cadena, '\0', 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1 + strlen(bufferIdProceso) + 1 + strlen(bufferIdThread) + 1 + 1 + 1 + strlen(comentario) + 1 + 1);
		 strcpy(cadena, "[");
		 strcpy(cadena + 1, tipo);
		 strcpy(cadena + 1 + strlen(tipo), "]");
		 strcpy(cadena + 1 + strlen(tipo) + 1, " ");
		 strcpy(cadena + 1 + strlen(tipo) + 1 + 1, bufferTiempo);
		 strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo), " ");
		 strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1, nombreProceso);
		 strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso), "/");
		 strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1, "(");
		 strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1, bufferIdProceso);
		 strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1 + strlen(bufferIdProceso), ":");
		 strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1 + strlen(bufferIdProceso) + 1, bufferIdThread);
		 strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1 + strlen(bufferIdProceso) + 1 + strlen(bufferIdThread), ")");
		 strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1 + strlen(bufferIdProceso) + 1 + strlen(bufferIdThread) + 1, " ");
		 strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1 + strlen(bufferIdProceso) + 1 + strlen(bufferIdThread) + 1 + 1, comentario);
		 strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1 + strlen(bufferIdProceso) + 1 + strlen(bufferIdThread) + 1 + 1 + strlen(comentario), "\n");

		 free(buffer);
		 free(bufferTiempo);
		 free(bufferIdProceso);
		 free(bufferIdThread);

		 loguearCadena(cadena, nivelLog);

		 free(cadena);*/
		char buffer[20];
		memset(buffer, '\0', 20);
		struct tm* tiempoLocal;
		tiempoLocal = localtime(&tiempo);
		strftime(buffer, 80, "%H:%M:%S:000", tiempoLocal);
		loguearTemplate(nivelLog, "[%s] %s %s/(%d:%d): %s\n", tipo, buffer, nombreProceso, idProceso, idThread, comentario);
	}
}

void loguearTemplate(uint8_t nivelLog, char* template, ...) {
	if (nivelLogActual > 0 && nivelLogActual >= nivelLog) {
		va_list arg;
		va_start(arg, template);
		char log[MAX_LINEA_LOG];
		memset(log, '\0', MAX_LINEA_LOG);
		vsprintf(log, template, arg);
		loguearCadena(log, nivelLog);
	}
}

void loguearDatosTemplate(char* tipo, time_t tiempo, char* nombreProceso, uint32_t idProceso, uint32_t idThread, uint8_t nivelLog, char* template, ...) {
	if (nivelLogActual > 0 && nivelLogActual >= nivelLog) {
		va_list arg;
		va_start(arg, template);

		char buffer[20];
		memset(buffer, '\0', 20);
		struct tm* tiempoLocal;
		tiempoLocal = localtime(&tiempo);
		strftime(buffer, 80, "%H:%M:%S:000", tiempoLocal);

		char primerTemplate[MAX_LINEA_LOG];
		memset(primerTemplate, '\0', MAX_LINEA_LOG);
		sprintf(primerTemplate,"[%s] %s %s/(%d:%d):",tipo, buffer, nombreProceso, idProceso, idThread);

		char segundoTemplate[MAX_LINEA_LOG];
		memset(segundoTemplate, '\0', MAX_LINEA_LOG);
		vsprintf(segundoTemplate,template,arg);

		char log[MAX_LINEA_LOG];
		memset(log, '\0', MAX_LINEA_LOG);
		sprintf(log, "%s %s\n",primerTemplate, segundoTemplate);
		loguearCadena(log, nivelLog);
	}
}

void cerrarArchivoLog(void) {
	pthread_mutex_lock(&mutexArchLogs);
	close(fp);
	fp = -1;
	pthread_mutex_unlock(&mutexArchLogs);
}
